package com.tianji.learning.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.leanring.LearningLessonDTO;
import com.tianji.api.dto.leanring.LearningRecordDTO;
import com.tianji.api.dto.remark.LikedTimesDTO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.exceptions.BizIllegalException;
import com.tianji.common.exceptions.DbException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domin.dto.LearningRecordFormDTO;
import com.tianji.learning.domin.po.LearningLesson;
import com.tianji.learning.domin.po.LearningRecord;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.enums.SectionType;
import com.tianji.learning.mapper.LearningRecordMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.tianji.learning.service.ILearningRecordService;
import com.tianji.learning.utils.LearningRecordDelayTaskHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 学习记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-08-29
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LearningRecordServiceImpl extends ServiceImpl<LearningRecordMapper, LearningRecord> implements ILearningRecordService {

    private final ILearningLessonService learningLessonService;

    private final CourseClient courseClient;
    private final LearningRecordDelayTaskHandler taskHandler;
    private final RabbitMqHelper mqHelper;

    @Override
    public LearningLessonDTO queryLearningRecordByCourse(Long courseId) {
        //获取用户id
        Long userId = UserContext.getUser();

        //查询课表 条件 用户id、课程id
        LearningLesson learningLesson = learningLessonService.lambdaQuery().eq(LearningLesson::getUserId, userId).eq(LearningLesson::getCourseId, courseId).one();
        if (learningLesson == null) {
            throw new BizIllegalException("该课程未加入课表");
        }
        //查询学习记录表 条件 课表id
        List<LearningRecord> records = lambdaQuery().eq(LearningRecord::getLessonId, learningLesson.getId()).list();

        //封装DTO返回
        LearningLessonDTO learningLessonDTO = new LearningLessonDTO();
        learningLessonDTO.setId(learningLesson.getId());
        learningLessonDTO.setLatestSectionId(learningLesson.getLatestSectionId());
        learningLessonDTO.setRecords(BeanUtils.copyList(records, LearningRecordDTO.class));
        return learningLessonDTO;
    }

    @Override
    public void addLearningRecords(LearningRecordFormDTO learningRecordDTO) {
        //获取当前用户ID
        Long userId = UserContext.getUser();
        //处理学习记录
        //小节是否学完
        boolean isFinished;
        if (learningRecordDTO.getSectionType().equals(SectionType.VIDEO)) {
            //处理视频播放记录
            isFinished = handleVideoRecord(userId, learningRecordDTO);
        } else {
            //处理考试记录
            isFinished = handleExamRecord(userId, learningRecordDTO);
        }
        if(!isFinished){
            return;
        }

        //处理课表记录
        handleLessonData( learningRecordDTO);
    }



    private void handleLessonData(LearningRecordFormDTO dto) {


        //获取课表
        LearningLesson learningLesson = learningLessonService.getById(dto.getLessonId());
        if (learningLesson == null) {
            throw new BizIllegalException("课表不存在");
        }
        boolean allFinish = false;

            //获取课程
            CourseFullInfoDTO courseInfo = courseClient.getCourseInfoById(learningLesson.getCourseId(), false, false);
            if (courseInfo == null) {
                throw new BizIllegalException("课程不存在，无法更新数据！");
            }
            //判断是否学完全部小节
            allFinish = learningLesson.getLearnedSections() + 1 >= courseInfo.getSectionNum();


        //更新课表
        learningLessonService.lambdaUpdate().set(learningLesson.getStatus().equals(LessonStatus.NOT_BEGIN), LearningLesson::getStatus, LessonStatus.LEARNING)
                .set(allFinish, LearningLesson::getStatus, LessonStatus.FINISHED)
                .set(LearningLesson::getLatestSectionId, dto.getSectionId())
                .set(LearningLesson::getLatestLearnTime, dto.getCommitTime())
                .setSql("learned_sections = learned_sections + 1")
                .eq(LearningLesson::getId, dto.getLessonId()).update();

        //发送积分消息
        mqHelper.send(MqConstants.Exchange.LEARNING_EXCHANGE,MqConstants.Key.LEARN_SECTION,10);
    }

    private boolean handleExamRecord(Long userId, LearningRecordFormDTO learningRecordDTO) {
        LearningRecord learningRecord = BeanUtils.copyBean(learningRecordDTO, LearningRecord.class);
        learningRecord.setUserId(userId);
        learningRecord.setFinished(true);
        learningRecord.setFinishTime(learningRecordDTO.getCommitTime());
        boolean save = save(learningRecord);
        if (!save) {
            throw new DbException("新增学习记录失败");
        }
        return false;
    }

    private boolean handleVideoRecord(Long userId, LearningRecordFormDTO learningRecordDTO) {
        //查找学习记录 条件lessonID、sectionID
        LearningRecord learningRecord = queryRedis(learningRecordDTO.getLessonId(), learningRecordDTO.getSectionId());

        //添加学习记录
        if (learningRecord == null) {
            LearningRecord record = BeanUtils.copyBean(learningRecordDTO, LearningRecord.class);
            record.setUserId(userId);
            boolean save = save(record);
            if (!save) {
                throw new DbException("新增视频记录失败");
            }
            return false;
        }
        boolean isFinish = !learningRecord.getFinished() && learningRecordDTO.getMoment() * 2 >= learningRecordDTO.getDuration();
        if (!isFinish) {
            LearningRecord record = new LearningRecord();
            record.setFinished(learningRecord.getFinished());
            record.setMoment(learningRecordDTO.getMoment());
            record.setId(learningRecord.getId());
            record.setLessonId(learningRecordDTO.getLessonId());
            record.setSectionId(learningRecordDTO.getSectionId());
            taskHandler.addLearningRecordTask(record);
            return false;
        }
        //更新学习记录 更新moment、finished、finishTime
        boolean update = lambdaUpdate()
                .set(LearningRecord::getMoment, learningRecordDTO.getMoment())
                .set(LearningRecord::getFinished, true)
                .set(LearningRecord::getFinishTime, learningRecordDTO.getCommitTime())
                .eq(LearningRecord::getId, learningRecord.getId()).update();

        if (!update) {
            throw new DbException("更新学习记录失败");
        }

        //清除redis缓存
        taskHandler.cleanRecordCache(learningRecordDTO.getLessonId(), learningRecordDTO.getSectionId());
        return true;
    }

    private LearningRecord queryRedis(Long lessonId, Long sectionId) {
        LearningRecord learningRecord = taskHandler.readRecordCache(lessonId, sectionId);

        if (learningRecord != null) {

            return learningRecord;
        }

        LearningRecord DbLearningRecord = lambdaQuery().eq(LearningRecord::getLessonId, lessonId).eq(LearningRecord::getSectionId, sectionId).one();

        if (DbLearningRecord == null) {
            return null;
        }


        taskHandler.writeRecordCache(DbLearningRecord);

        return DbLearningRecord;
    }
}
